package com.jyxd.web.service.assessment.basic;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.jyxd.web.dao.basic.MonitorLifeDataDao;
import com.jyxd.web.dao.basic.RespiratorDataDao;
import com.jyxd.web.dao.basic.VitalSignMergeDao;
import com.jyxd.web.dao.patient.PatientDao;
import com.jyxd.web.data.basic.MonitorLifeData;
import com.jyxd.web.data.basic.NurseRecordForm;
import com.jyxd.web.data.basic.RespiratorData;
import com.jyxd.web.data.basic.VitalSignMerge;
import com.jyxd.web.data.dto.BaseDataDto;
import com.jyxd.web.data.dto.HttpResult;
import com.jyxd.web.data.dto.TemperatureMomentDTO;
import com.jyxd.web.data.patient.Patient;
import com.jyxd.web.data.user.User;
import com.jyxd.web.mq.HisViewProduction;
import com.jyxd.web.service.hisview.dto.HisViewDataDto;
import com.jyxd.web.service.patient.PatientScoreService;
import com.jyxd.web.util.UUIDUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpSession;
import java.text.ParseException;
import java.util.*;

import static com.jyxd.web.config.ConstantConfig.*;
import static com.jyxd.web.util.DateUtil.*;
import static com.jyxd.web.util.ExecuteUtil.errorIfEmpty;
import static com.jyxd.web.util.UUIDUtil.getUUID;
import static com.jyxd.web.util.VitalSignUtil.queryIsEmpty;

/**
 * 生命体征2合一表
 */
@Service
@Transactional
public class VitalSignMergeService {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private VitalSignMergeDao vitalSignMergeDao;

    @Autowired
    private MonitorLifeDataDao monitorLifeDataDao;

    @Autowired
    private MonitorLifeDataService monitorLifeDataService;

    @Autowired
    private PatientDao patientDao;

    @Autowired
    private PatientScoreService patientScoreService;

    @Autowired
    private BloodSugarService bloodSugarService;

    @Autowired
    private AbpService abpService;

    @Autowired
    private RespiratorDataDao respiratorDataDao;

    @Autowired
    private CommonSettingService commonSettingService;

    @Autowired
    private NurseRecordFormService nurseRecordFormService;
    @Autowired
    private HisViewProduction hisViewProduction;

    public boolean insert(VitalSignMerge vitalSign) {
        return vitalSignMergeDao.insert(vitalSign);
    }

    public boolean update(VitalSignMerge vitalSign) {
        return vitalSignMergeDao.update(vitalSign);
    }

    public VitalSignMerge queryData(String id) {
        return vitalSignMergeDao.queryData(id);
    }

    public List<VitalSignMerge> queryList(Map<String, Object> map) {
        return vitalSignMergeDao.queryList(map);
    }

    public int queryNum(Map<String, Object> map) {
        return vitalSignMergeDao.queryNum(map);
    }

    //体温单相关=================================================================
    private static String time1 = "03";
    private static String time2 = "07";
    private static String time3 = "11";
    private static String time4 = "15";
    private static String time5 = "19";
    private static String time6 = "23";

    /**
     * 体温单查询数据
     *
     * @param patientId
     * @param dateDayList
     * @param code
     * @return
     */
    public List<TemperatureMomentDTO> findTemperatureCodeData(String patientId, List<String> dateDayList, String code) {
        errorIfEmpty(dateDayList, "查询时间集合不存在");
        List<TemperatureMomentDTO> temperatureDayList = new ArrayList<>();
        List<String> timeList = new ArrayList<String>();
        for (String s : dateDayList) {
            timeList.add(s + " " + time1);
            timeList.add(s + " " + time2);
            timeList.add(s + " " + time3);
            timeList.add(s + " " + time4);
            timeList.add(s + " " + time5);
            timeList.add(s + " " + time6);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("patientId", patientId);
        if ("hr".equals(code)) {
            map.put("hr", "hr");
        }
        if ("br".equals(code)) {
            map.put("br", "br");
        }
        if ("temperature".equals(code)) {
            map.put("temperature", "temperature");
        }
        map.put("list", timeList);
        List<TemperatureMomentDTO> maplist = vitalSignMergeDao.findTemperatureMomentVitalSignByCode(map);
        if ("br".equals(code)) {
            for (int i = 0; i < timeList.size(); i++) {
                TemperatureMomentDTO dto = new TemperatureMomentDTO();
                String hours = "";
                String br = "";
                String mode = "";
                for (int j = 0; j < maplist.size(); j++) {
                    TemperatureMomentDTO tDto = maplist.get(j);
                    if (timeList.get(i).equals(tDto.getTimes())) {
                        br = tDto.getBr();
                        mode = tDto.getModeValue();
                    }
                }
                if (!"".equals(br) && !"".equals(mode) && mode != null) {
                    br = "®";
                }
                dto.setBr(br);
                temperatureDayList.add(dto);
            }
        } else {
            for (int i = 0; i < timeList.size(); i++) {
                TemperatureMomentDTO dto = null;
                String hours = "";
                String hr = "";
                String tempalate = "";
                for (int j = 0; j < maplist.size(); j++) {
                    TemperatureMomentDTO tDto = maplist.get(j);
                    if (timeList.get(i).equals(tDto.getTimes())) {
                        dto = new TemperatureMomentDTO();
                        hours = tDto.getHours().replaceFirst("^0*", "");
                        if ("hr".equals(code)) {
                            hr = tDto.getHr();
                        }
                        if ("temperature".equals(code)) {
                            tempalate = tDto.getTemperature();
                        }
                    }
                }
                if (dto != null) {
                    dto.setMoment(Integer.parseInt(hours) + 24 * (i / 6));
                    if ("hr".equals(code)) {
                        dto.setHr(hr);
                    }
                    if ("temperature".equals(code)) {
                        dto.setTemperature(tempalate);
                    }
                    temperatureDayList.add(dto);
                }
            }
        }
        return temperatureDayList;
    }

    /**
     * 同步生命体征到二合一生命体征表中
     *
     * @param requestMap
     * @param user
     */
    public HttpResult syncVitalSignMerge(Map<String, String> requestMap, User user) throws ParseException {
        queryIsEmpty(requestMap);
        String time = requestMap.get("time");
        String patientId = requestMap.get("patientId");
        Patient patient = patientDao.queryData(patientId);
        if (Objects.isNull(patient))
            return new HttpResult(200, "患者数据不存在同步失败");
        if (!Objects.equals(patient.getFlag(), 1) || Objects.equals(patient.getStatus(), -1))
            return new HttpResult(200, "该患者属于出科或删除状态，不进行监护仪数据同步");
        MonitorLifeData monitorLifeData = findMonitorLifeData(time, patientId);
        if (Objects.isNull(monitorLifeData))
            return new HttpResult(200, "查询监护仪数据不存在");
        logger.info("监护仪数据为：" + JSON.toJSONString(monitorLifeData));
        // 判断同步新的生命体征表单还是旧的生命体征表单
        return nurseRecordFormService.saveNurseRecordFormData(patient, time, monitorLifeData, user); // 同步到新的生命体征表单
    }

    /**
     * 获取小于某个时间内的呼吸机数据
     *
     * @param time
     * @param patientId
     * @return
     * @throws ParseException
     */
    private RespiratorData getRespiratorDataByTime(Date time, String patientId) {
        Map<String, Object> map = new HashMap<>();
        map.put("time", time);
        map.put("patientId", patientId);
        List<RespiratorData> respiratorData = respiratorDataDao.getTimeAndPatientId(map);
        if (CollectionUtils.isEmpty(respiratorData))
            return null;
        Date startTime = getLaterMinuteDate(time, -10L);
        map.put("time", startTime);
        respiratorData = respiratorDataDao.getTimeAndPatientId(map);
        if (CollectionUtils.isEmpty(respiratorData))
            return null;
        return respiratorData.get(0);
    }


    /**
     * 更新旧的数据
     */
    private void updateOldData(VitalSignMerge vitalSignMerge, MonitorLifeData monitorLifeData,
                               boolean isOpenPulseRecord, User user, Patient patient) throws ParseException {
        // 赋值生命体征监护仪数据
        setVitalData(vitalSignMerge, monitorLifeData, isOpenPulseRecord, user);
        // 赋值生命体征呼吸机数据 todo 呼吸机暂时未接入
        // syncModeData(vitalSignMerge.getDataTime(), vitalSignMerge.getPatientId(), vitalSignMerge);
        vitalSignMergeDao.update(vitalSignMerge);
        // 自动同步生命体征时，新增无创血压单
        syncArts(vitalSignMerge);
        // 自动同步时时，新增数据到数据中心
        hisViewProduction.put(new HisViewDataDto(HIS_VIEW_EVENT_DC_HlLCZJL_BZBWHL, patient, vitalSignMerge));
        // 自动同步生命体征时，新增体征记录数据到数据中心
        hisViewProduction.put(new HisViewDataDto(HIS_VIEW_EVENT_DC_ICU_DAT_TZJL, patient, vitalSignMerge));
    }

    /**
     * 生成新的生命体征数据
     *
     * @param patient
     * @param time
     * @param monitorLifeData
     */
    private void newSaveVitalSignMerge(Patient patient, Date time,
                                       MonitorLifeData monitorLifeData, boolean isOpenPulseRecord, User user) throws ParseException {
        VitalSignMerge vitalSignMerge = new VitalSignMerge();
        vitalSignMerge.setId(getUUID());
        vitalSignMerge.setCreateTime(new Date());
        vitalSignMerge.setUpdateTime(new Date());
        vitalSignMerge.setPatientId(patient.getId());
        vitalSignMerge.setVisitCode(patient.getVisitCode());
        vitalSignMerge.setVisitId(patient.getVisitId());
        vitalSignMerge.setDataTime(time);
        vitalSignMerge.setStatus(1);
        // 赋值监护仪体征数据
        setVitalData(vitalSignMerge, monitorLifeData, isOpenPulseRecord, user);
        // 赋值最新的无变化数据
        setOldInvariantData(vitalSignMerge, time);
        // 赋值呼吸机数据 todo 呼吸机暂时未接入
        // syncModeData(vitalSignMerge.getDataTime(), vitalSignMerge.getPatientId(), vitalSignMerge);
        // 自动同步生命体征时，新增无创血压单
        syncArts(vitalSignMerge);
        // 自动同步生命体征时，新增到数据中心
        hisViewProduction.put(new HisViewDataDto(HIS_VIEW_EVENT_DC_HlLCZJL_BZBWHL, patient, vitalSignMerge));
        // 自动同步生命体征时，新增体征记录数据到数据中心
        hisViewProduction.put(new HisViewDataDto(HIS_VIEW_EVENT_DC_ICU_DAT_TZJL, patient, vitalSignMerge));
        vitalSignMergeDao.insert(vitalSignMerge);
    }

    /**
     * 赋值旧的不变的数据
     */
    private void setOldInvariantData(VitalSignMerge vitalSignMerge, Date time) {
        Map<String, Object> map = new HashMap<>();
        map.put("patientId", vitalSignMerge.getPatientId());
        map.put("endTime", yyyyMMddHHmmssSdfToString(time));
        VitalSignMerge oldVitalSignMerge = vitalSignMergeDao.queryByPatientAndDataTime(map);
        if (Objects.isNull(oldVitalSignMerge))
            return;
        vitalSignMerge.setConsciousness(oldVitalSignMerge.getConsciousness()); // 意识
        vitalSignMerge.setDragFlag(oldVitalSignMerge.getDragFlag()); // 是否使用药物
        vitalSignMerge.setPupilSizeLeft(oldVitalSignMerge.getPupilSizeLeft()); // 瞳孔大小左
        vitalSignMerge.setPupilSizeRight(oldVitalSignMerge.getPupilSizeRight());// 瞳孔大小右
        vitalSignMerge.setPupilResponseLeft(oldVitalSignMerge.getPupilResponseLeft()); // 瞳孔反应左
        vitalSignMerge.setPupilResponseRight(oldVitalSignMerge.getPupilResponseRight()); // 瞳孔反应右
        vitalSignMerge.setHeartRhythm(oldVitalSignMerge.getHeartRhythm()); // 心律
        vitalSignMerge.setBak5(oldVitalSignMerge.getBak5()); // 吸氧方式
        // 呼吸系统自动赋值
        vitalSignMerge.setMode(oldVitalSignMerge.getMode()); // mode
        vitalSignMerge.setFio2(oldVitalSignMerge.getFio2()); // fio2
        vitalSignMerge.setVt(oldVitalSignMerge.getVt()); // vt
        vitalSignMerge.setBak4(oldVitalSignMerge.getBak4()); // pinsp/pcv
        vitalSignMerge.setPs(oldVitalSignMerge.getPs()); // ps
        vitalSignMerge.setPeep(oldVitalSignMerge.getPeep()); // peep
        vitalSignMerge.setIpap(oldVitalSignMerge.getIpap()); // ipap
        vitalSignMerge.setCritical(oldVitalSignMerge.getCritical()); // 危急值
        if (StringUtils.isNotEmpty(oldVitalSignMerge.getChecksign()))  // 赋值签名 ， 如果有接班签名则获取上一条签名，否则赋值旧的签名
            vitalSignMerge.setSign(oldVitalSignMerge.getChecksign());
        else
            vitalSignMerge.setSign(oldVitalSignMerge.getSign());
    }

    /**
     * 赋值监护仪数据到生命体征表
     *
     * @param vitalSignMerge
     * @param monitorLifeData
     */
    private void setVitalData(VitalSignMerge vitalSignMerge, MonitorLifeData monitorLifeData,
                              boolean isOpenPulseRecord, User user) {
        if (StringUtils.isNotEmpty(monitorLifeData.getTemp()))
            vitalSignMerge.setTemplate(monitorLifeData.getTemp()); // 赋值体温
        if (StringUtils.isNotEmpty(monitorLifeData.getHr()))
            vitalSignMerge.setHr(monitorLifeData.getHr()); // 赋值心率
        if (StringUtils.isNotEmpty(monitorLifeData.getPulse()) && isOpenPulseRecord)
            vitalSignMerge.setPulse(monitorLifeData.getPulse()); //赋值脉搏
        if (StringUtils.isNotEmpty(monitorLifeData.getResp()))
            vitalSignMerge.setBr(monitorLifeData.getResp()); //赋值呼吸
        if (StringUtils.isNotEmpty(monitorLifeData.getNibps()) && StringUtils.isNotEmpty(monitorLifeData.getNibpd()))
            vitalSignMerge.setNbp(monitorLifeData.getNibps() + "/" + monitorLifeData.getNibpd()); // 赋值无创血压
        if (StringUtils.isNotEmpty(monitorLifeData.getArts()) && StringUtils.isNotEmpty(monitorLifeData.getArtd()))
            vitalSignMerge.setAbp(monitorLifeData.getArts() + "/" + monitorLifeData.getArtd()); // 赋值有创血压
        if (StringUtils.isNotEmpty(monitorLifeData.getSpo2()))
            vitalSignMerge.setSpO2(monitorLifeData.getSpo2()); //赋值血氧饱和
        if (Objects.nonNull(user)) {
            vitalSignMerge.setOperatorCode(user.getId());
            vitalSignMerge.setOperatorName(user.getUserName());
        }
    }

    /**
     * 获取监护仪数据
     *
     * @param time
     * @param patientId
     * @return
     * @throws ParseException
     */
    public MonitorLifeData findMonitorLifeData(String time, String patientId) throws ParseException {
        MonitorLifeData queryMonitorLifeData = new MonitorLifeData();
        queryMonitorLifeData.setDateTime(time);
        queryMonitorLifeData.setPatientId(patientId);
        List<MonitorLifeData> monitorLifeDataList = monitorLifeDataDao.queryList(queryMonitorLifeData);
        if (CollectionUtils.isEmpty(monitorLifeDataList)) {
            queryMonitorLifeData.setDateTime(null);
            queryMonitorLifeData.setDateEndTime(time);
            Date date = yyyyMMddHHmmSdfToDate(time);
            Date startTime = getLaterMinuteDate(date, -30L);
            queryMonitorLifeData.setDateStartTime(yyyyMMddHHmmssSdfToString(startTime));
            monitorLifeDataList = monitorLifeDataDao.queryList(queryMonitorLifeData);
            if (CollectionUtils.isEmpty(monitorLifeDataList)) {
                logger.info(patientId + "查询监护仪数据不存在");
                return null;
            }
        }
        return monitorLifeDataList.get(0);
    }

    public boolean saveData(VitalSignMerge vitalSign, HttpSession session) {
        User user = (User) session.getAttribute("user");

        vitalSign.setId(UUIDUtil.getUUID());
        vitalSign.setCreateTime(new Date());
        vitalSign.setOperatorCode(user.getId());
        vitalSign.setOperatorName(user.getUserName());
        vitalSign.setStatus(1);
        //判断传入的生命体征信息是否为空，如果为空，自动查询传入时间的生命体征数据进行补充
        Patient patient = patientDao.queryData(vitalSign.getPatientId());
        vitalSign = setVitalSignContent(vitalSign, patient);
        // 新增生命体征时，新增无创血压单或血糖单
        syncArts(vitalSign);
        syncBloodGlucose(vitalSign);
        // 新增生命体征时，新增数据到数据中心
        hisViewProduction.put(new HisViewDataDto(HIS_VIEW_EVENT_DC_HlLCZJL_BZBWHL, patient, vitalSign));
        // 修改时生命体征时，新增护理观察数据到数据中心
        hisViewProduction.put(new HisViewDataDto(HIS_VIEW_EVENT_DC_HLCZJL_BZBWHL_HLGC, vitalSign));
        // 修改时生命体征时，新增体征记录数据到数据中心
        hisViewProduction.put(new HisViewDataDto(HIS_VIEW_EVENT_DC_ICU_DAT_TZJL, vitalSign));
        return insert(vitalSign);
    }

    private VitalSignMerge setVitalSignContent(VitalSignMerge vitalSign, Patient patient) {
        return (VitalSignMerge) monitorLifeDataService.setObjectMonitorLifeData(patient, yyyyMMddHHmmssSdfToString(vitalSign.getDataTime()), vitalSign);

    }


    public void syncArts(VitalSignMerge vitalSignMerge) {
        errorIfEmpty(vitalSignMerge, "生命体征数据为空");
        if (Objects.isNull(vitalSignMerge.getAbp()) || vitalSignMerge.getAbp() == "" || vitalSignMerge.getAbp() == "null/null")
            return;
        abpService.saveOrUpdate(new BaseDataDto(vitalSignMerge.getPatientId(), vitalSignMerge.getId(), vitalSignMerge.getAbp(),
                vitalSignMerge.getDataTime(), vitalSignMerge.getSign()));
    }

    /**
     * 自动同步血糖数据到血糖单
     *
     * @param vitalSignMerge
     */
    public void syncBloodGlucose(VitalSignMerge vitalSignMerge) {
        errorIfEmpty(vitalSignMerge, "生命体征数据为空");
        if (Objects.isNull(vitalSignMerge.getBak6()) || vitalSignMerge.getBak6() == "")
            return;
        bloodSugarService.saveOrUpdate(new BaseDataDto(vitalSignMerge.getPatientId(), vitalSignMerge.getId(), vitalSignMerge.getBak6(),
                vitalSignMerge.getDataTime(), vitalSignMerge.getSign()));
    }

    /**
     * 体温查询所有的数据
     *
     * @param patientId
     * @param dateDayList
     * @param code
     * @return
     */
    public List<TemperatureMomentDTO> findTemperatureCode(String patientId, List<String> dateDayList, String code) {
        errorIfEmpty(dateDayList, "查询时间集合不存在");
        List<TemperatureMomentDTO> temperatureDayList = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        map.put("patientId", patientId);
        map.put("temperature", "temperature");
        map.put("list", dateDayList);
        List<TemperatureMomentDTO> maplist = vitalSignMergeDao.findTemperatureMomentVitalSignByCodeTemp(map);
        for (int i = 0; i < dateDayList.size(); i++) {

            for (int j = 0; j < maplist.size(); j++) {
                TemperatureMomentDTO tDto = maplist.get(j);
                if (dateDayList.get(i).equals(tDto.getTimes())) {
                    //将时间转成小时
                    TemperatureMomentDTO dto = new TemperatureMomentDTO();
                    String hours = tDto.getHours();
                    String minutes = tDto.getMinutes();
                    double min = Double.parseDouble(minutes) / 60;
                    String str = String.format("%.2f", min);
                    double four = Double.parseDouble(str);
                    double moment = four + Double.parseDouble(hours);
                    dto.setMoment2(moment);
                    dto.setMoment(i);
                    dto.setTemperature(tDto.getTemperature());
                    temperatureDayList.add(dto);
                }
            }
        }

        return temperatureDayList;
    }

    public void syncVitalSignMerge(NurseRecordForm nurseRecordForm) {
        if(Objects.nonNull(nurseRecordForm) && Objects.nonNull(nurseRecordForm.getDataTime()) && StringUtils.isNotBlank(nurseRecordForm.getTemplate())){
            Date dataTime = nurseRecordForm.getDataTime();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(dataTime);
            int hour = calendar.get(Calendar.HOUR_OF_DAY);
            int minute = calendar.get(Calendar.MINUTE);
            int second = calendar.get(Calendar.SECOND);
            if (StrUtil.equalsAny(String.valueOf(hour), "3", "7", "11", "15", "19", "23") && minute == 0 && second == 0) {
                VitalSignMerge vitalSignMerge = new VitalSignMerge();
                vitalSignMerge.setTemplate(nurseRecordForm.getTemplate());
                vitalSignMerge.setBr(nurseRecordForm.getBr());
                vitalSignMerge.setHr(nurseRecordForm.getHr());
                vitalSignMerge.setStatus(1);
                vitalSignMerge.setId(getUUID());
                vitalSignMerge.setPatientId(nurseRecordForm.getPatientId());
                vitalSignMerge.setDataTime(dataTime);
                vitalSignMergeDao.saveOrUpdate(vitalSignMerge);
            }
        }
    }
}
